package c03数据类型和运算符;

public class 字符串地址研究 {

	private static final String ss0 = "ab";
	private static final String ss1 = "ab";

	public static void main(String[] args) {
		String s0 = "ab";
		String s1 = new String("ab");
		String s2 = "a" + "b";
		String sa = "a";
		String sb = "b";
		String sab = sa + sb;
		String nsab = new String("a") + new String("b");
		final String fsa = "a";
		final String fsb = "b";
		String fsab = fsa + fsb;

		//类常量 ss0,ss1 和局部变量 s0 都是引用堆中字符串池的字符串, 所以下面3行都是true
		System.err.println(ss0 == ss1);//true！
		System.err.println(s0 == ss0);//true！
		System.err.println(s0 == ss1);//true！

		System.err.println("----------------");
		System.err.println(s0=="ab");//true！
		System.err.println(s0 == s1);//false！new String("ab")在这里会复制字符串池的"ab"到堆内存创建对象, 故两者不同对象, 因此返回false！
		System.err.println(s0 == s2);//true！s2编译成字节码时就可以确定是"ab"，故引用的是字符串池的"ab", 故为true！
		System.err.println(s0 == sab);//false！sa,sb是变量, 在字节码中其实会自动创建StringBuilder来拼接这两个字符串, 最后toString()会创建一个堆字符串得为结果, 因此返回false！
		System.err.println(s1 == sab);//false！两者虽然都是堆内存的对象，但不是同一个, false！
		System.err.println(s0 == nsab);//false！nsab跟sab都会自动用到StringBuilder来拼接结果, 故返回false
		System.err.println(s0 == fsab);//true！final使fsa和fsb不可变，故fsab可以在编译成字节码时确定为"ab", 因此返回true！
		System.err.println(s1 == fsab);//false！

		System.err.println("----------------");
		System.err.println(ss0==字符串地址研究2.ss0);//true！[字符串地址研究2.ss0="ab"], 不同类可以共用字符串常量池中内容相同的字符串!
	}

}
